﻿//SecurityPicker.xaml.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Xaml
{
	using System;
	using System.Collections.Generic;
	using System.Collections.ObjectModel;
	using System.Collections.Specialized;
	using System.Linq;
	using System.Windows.Controls;
	using System.Windows.Input;

	using Ecng.Common;
	using Ecng.Collections;
	using Ecng.Xaml;

	using StockSharp.BusinessEntities;

	/// <summary>
	/// Визуальный компонент для поиска и выбора инструмента.
	/// </summary>
	public partial class SecurityPicker
	{
		private const SecurityTypes _nullType = (SecurityTypes)(-1);
		private readonly ObservableCollection<Security> _visibleSecurities = new ObservableCollection<Security>();
		private readonly WrappedList<object, Security> _selectedSecurities; 

		/// <summary>
		/// Создать <see cref="SecurityPicker"/>.
		/// </summary>
		public SecurityPicker()
		{
			InitializeComponent();

			Securities = new ThreadSafeObservableCollection<Security>();
			Securities.CollectionChanged += (s, a) =>
			{
				if (a.Action == NotifyCollectionChangedAction.Add || a.Action == NotifyCollectionChangedAction.Reset || a.Action == NotifyCollectionChangedAction.Remove)
					FilterSecurities();
			};

			ListViewSecurities.ItemsSource = _visibleSecurities;
			SecurityTypeCtrl.SetDataSource<SecurityTypes>();
			SecurityTypeCtrl.GetItemsSource().Insert(0, new EnumComboBox.EnumerationMember
			{
				Description = "Все",
				Value = _nullType,
			});
			SecurityType = null;

			_selectedSecurities = new WrappedList<object, Security>((IList<object>)ListViewSecurities.SelectedItems);
		}

		/// <summary>
		/// События двойного нажатия мышкой на выбранный инструмент.
		/// </summary>
		public event Action<Security> SecurityDoubleClick;

		/// <summary>
		/// События изменения выбранного инструмента.
		/// </summary>
		public event Action<Security> SecuritySelected;

		/// <summary>
		/// Выбранный инструмент.
		/// </summary>
		public Security SelectedSecurity
		{
			get { return (Security)ListViewSecurities.SelectedItem; }
			set
			{
				ListViewSecurities.SelectedItems.Clear();
				ListViewSecurities.SelectedItem = value;

				if (value == null)
					return;

				ListViewSecurities.ScrollIntoView(value);

				var item = (ListViewItem)ListViewSecurities.ItemContainerGenerator.ContainerFromItem(value);

				if (item != null)
					item.Focus();
			}
		}

		/// <summary>
		/// Выбранные инструменты.
		/// </summary>
		public IList<Security> SelectedSecurities
		{
			get { return _selectedSecurities; }
		}

		/// <summary>
		/// Выбранный тип инструмента.
		/// </summary>
		public SecurityTypes? SecurityType
		{
			get
			{
				var type = SecurityTypeCtrl.GetSelectedValue<SecurityTypes>();
				return type == _nullType ? null : type;
			}
			set
			{
				SecurityTypeCtrl.SetSelectedValue<SecurityTypes>(value ?? _nullType);
			}
		}

		/// <summary>
		/// Текущий фильтр по инструменту.
		/// </summary>
		public string SecurityFilter
		{
			get { return SecurityName.Text; }
			set { SecurityName.Text = value; }
		}

		/// <summary>
		/// Доступные инструменты.
		/// </summary>
		public ThreadSafeObservableCollection<Security> Securities { get; private set; }

		private ITrader _trader;

		/// <summary>
		/// Шлюз к торговой системе.
		/// </summary>
		public ITrader Trader
		{
			get { return _trader; }
			set
			{
				if (_trader != value)
				{
					if (_trader != null)
					{
						_trader.NewSecurities -= OnNewSecurities;
						Securities.Clear();
						_visibleSecurities.Clear();
					}

					_trader = value;

					if (_trader != null)
					{
						OnNewSecurities(_trader.Securities);
						_trader.NewSecurities += OnNewSecurities;
					}
				}
			}
		}

		private void OnNewSecurities(IEnumerable<Security> securities)
		{
			securities.ForEach(s=>Securities.Add(s));
		}

		private void FilterSecurities()
		{
			_visibleSecurities.Clear();

			var filter = SecurityFilter.ToLowerInvariant();

			var secType = SecurityType;

			if (secType == null && filter.IsEmpty())
			{
				_visibleSecurities.AddRange(Securities.ToList());
			}
			else
			{
				_visibleSecurities.AddRange(Securities.Where(s =>
					(secType == null || s.Type == secType) &&
					(filter.IsEmpty() || (!s.Code.IsEmpty() && s.Code.ContainsIgnoreCase(filter)) ||
					(!s.Name.IsEmpty() && s.Name.ContainsIgnoreCase(filter)) ||
					s.Id.ContainsIgnoreCase(filter))).ToList());
			}
		}

		private void HandleDoubleClick(object sender, MouseButtonEventArgs e)
		{
			SecurityDoubleClick.SafeInvoke((Security)((ListViewItem)sender).DataContext);
			e.Handled = true;
		}

		private void SecurityTypesSelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			FilterSecurities();
		}

		private void SecurityNameTextChanged(object sender, TextChangedEventArgs e)
		{
			FilterSecurities();
		}

		private void ListViewSecuritiesSelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			SecuritySelected.SafeInvoke(SelectedSecurity);
		}
	}
}